This document may be a little massi.. this is just served as an reference as I am current doing some experiment on caffe and wants to mark down something. I may make it tidy when I think it is time to :)
official caffe tour
nets, layers and blobs
layer
- layer categories: http://caffe.berkeleyvision.org/tutorial/layers.html
- each layer have 3 computation:
- setup
- initialization of the layer and its connections is done at model initialization.
- forward: bottom -(input)-> … -(output)-> top
- backward: top -(gradient wrt output)-> …compute gradient wrt parameters.. -(gradient)-> bottom
- takes the gradient with respect to the output, and computes the gradients with respect to the parameters and to the inputs
- setup
definition
1 | // 前四行-层属性 |
net
Blob
- defined in caffe_pb2.BlobProto
- attribute:
- data; diff; num; channels; height; width
- 4 dimension array
- data: number/N(batch size of the data), channel/K, height, width
- convolution weight: output, input, height, wifth
- convoluion bias: output 1 1 1
datum
- defined in caffe_pb2.BlobProto
- attribute: shape, channels, height, width, data,
- 3 dimensional array can be converted to datum by io.array_to_datum
#structure of caffe#
1.预处理图像的leveldb构建
输入:一批图像和label (2和3)
输出:leveldb (4)
指令里包含如下信息:
conver_imageset (构建leveldb的可运行程序)
train/ (此目录放处理的jpg或者其他格式的图像)
label.txt (图像文件名及其label信息)
输出的leveldb文件夹的名字
CPU/GPU (指定是在cpu上还是在gpu上运行code)
CNN网络配置文件
- network prototxt
Imagenet_solver.prototxt (包含全局参数的配置的文件)
Imagenet.prototxt (包含训练网络的配置的文件)
Imagenet_val.prototxt (包含测试网络的配置文件)
refer: http://www.csdn.net/article/2015-01-22/2823663
train your own model on your own data
- data preparation:
- The training and validation input are described in
train.txt
andval.txt
as text listing all the files and their labels - create the leveldbs with
examples/imagenet/create_imagenet.sh
- The training and validation input are described in
- Compute Image Mean:
The model requires us to subtract the image mean from each image, so we have to compute the mean.tools/compute_image_mean.cpp
the mean computation can be carried out as:
./examples/imagenet/make_imagenet_mean.sh
makedata/ilsvrc12/imagenet_mean.binaryproto
- Model Definition
models/bvlc_reference_caffenet/train_val.prototxt
noticed that the train and test network are both defined in this file and only the input layers and one output layer are different:
lay out a protocol buffer for running the solverfor training, data input: `examples/imagenet/ilsvrc12_train_leveldb` for testing, data input: `examples/imagenet/ilsvrc12_val_leveldb`
in `models/bvlc_reference_caffenet/solver.prototxt`.
file system
leveldb
- leveldb中数据按key/value形式存储。
- leveldb的使用介绍: http://zh.wikipedia.org/wiki/LevelDB
3.将图像以及标注信息,先经过Datum序列化成字符串,再存到leveldb数据库中。见tools/convert_imageset.cpp - leveldb学习资料: http://blog.csdn.net/hzqhbc/article/details/9367327
.py file
\python\caffe\classifier.py:1
2
caffe.Net
is the central interface for loading, configuring, and running models. caffe.Classsifier and caffe.Detector provide convenience interfaces for common tasks.caffe.SGDSolver
exposes the solving interface.caffe.io
handles input / output with preprocessing and protocol buffers.caffe.draw
visualizes network architectures.
Caffe blobs are exposed as numpy ndarrays for ease-of-use and efficiency.
callable python file:
classify.py
- argument:
input image,directory or npy
output npy filename
model-def file, default ../models/bvlc_reference_caffenet/deploy.prototxt
pretrain model -- trained model weight file
default ../models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel
--gpu switch to gpu mode
--center only, switch for prediction from center crop alone instead of averaging prediction across crops
-- image dim, default 256,256
mean_file default caffe/imagenet/ilsvrc_2012_mean.npy
--input scale, multiplly input features by this scale to finish preprocessing
--raw scale, multiply raw input by this scale before preprocessing
--channel_swap RGB-BGR since BGR is the caffe default by way of opencv
--ext default jpg, image file to take as input
--print-result, weite ourpur text or serializing to a file
- call classifier with
<!--2-->
- Load numpy array (.npy), directory glob (*.jpg), or image file.
1 | inputs = [caffe.io.load_image(args.input_file)] |
- classify and store
1 | predictions = classifier.predict(inputs, not args.center_only) |
for .proto file:
- write a .proto file
- compile with protoc
- command:
1
2
3
4protoc--proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR--python_out=DST_DIR path/to/file.proto
//
--proto_path 也可以简写成-I 是.proto所在的路径 输出路径: --cpp_out 要生成C++可用的头文件,分别是***.pb.h(包含申明类)***.pb.cc(包含可执行类),使用的时候只要include "***.pb.h" --java_out 生成java可用的头文件 --python_out 生成python可用的头文件,**_pb2.py,使用的时候import**_pb2.py即可 最后一个参数就是你的.proto文件完整路径。
type of prototxt
1 | // examples/feature_extraction/imaget_val.prototxt |
http://htmlpreview.github.io/?https://github.com/google/leveldb/blob/master/doc/index.html
documentation of leveldb
try to run lmdb2mat but say db.Get(‘$d’ $(im_indx)) not exist?
how to run plt in ssh? use xwin
http://www.arsc.edu/arsc/knowledge-base/ssh-and-x11-forwarding-us/index.xml
run 00classification, need:
.caffemodel file
read weights and biases for a caffemodel given the prototxt would be to just load the network in Python and read the weights.1
2import caffe
net = caffe.Net(<prototxt-file>,<model-file>,<phase>);
and access the params from net.params
READ DEPLOTTXT
type of layer
http://cs231n.github.io/convolutional-networks/
QQQQQ: why need mean of image
- data
conv1
- Just like normal Hidden Layer
- Connect neurons to the input in a local receptive field
- All neurons in a single depth slice share weights
relu
- norm
- pool
- fc: fully connect
- drop
Read the code! Two most important files:
http://vision.stanford.edu/teaching/cs231n/slides/caffe_tutorial.pdf
● caffe/python/caffe/_caffe.cpp:
○ Exports Blob, Layer, Net, and Solver classes
● caffe/python/caffe/pycaffe.py
○ Adds extra methods to Net class
name: “AlexNet”
input: “data”
input_shape {
dim: 10
dim: 3
dim: 227
dim: 227
}
layer {
name: “conv1”
type: “Convolution”
bottom: “data”
top: “conv1”
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
convolution_param {
num_output: 96
kernel_size: 11
stride: 4
}
}
layer {
name: “relu1”
type: “ReLU”
bottom: “conv1”
top: “conv1”
}
layer {
name: “norm1”
type: “LRN”
bottom: “conv1”
top: “norm1”
lrn_param {
local_size: 5
alpha: 0.0001
beta: 0.75
}
}
layer {
name: “pool1”
type: “Pooling”
bottom: “norm1”
top: “pool1”
pooling_param {
pool: MAX
kernel_size: 3
stride: 2
}
}
layer {
name: “pool2”
type: “Pooling”
bottom: “norm2”
top: “pool2”
pooling_param {
pool: MAX
kernel_size: 3
stride: 2
}
}
…
layer {
name: “fc7”
type: “InnerProduct”
bottom: “fc6”
top: “fc7”
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
inner_product_param {
num_output: 4096
}
}
…
param {
lr_mult: 2
decay_mult: 0
}
inner_product_param {
num_output: 1000
}
}
layer {
name: “prob”
type: “Softmax”
bottom: “fc8”
top: “prob”
}
pipline for python
\python\caffe\io.py
:
- conversion between datum, narray and proto(blob)
- preprocessing
- image IO
\python\caffe\net_spec.py
\python\caffe\draw.py
\examples\pycaffe\caffenet.py
def conv_relu, fc_relu, max_pool, caffenet(the net itself), make_net
preprocessing
- \python\caffe\io.py
- class Transformer,
- oversample
- \python\caffe\io.py
how to build a new layer:
- Add a class declaration for your layer to the appropriate one of
common_layers.hpp
,data_layers.hpp
,loss_layers.hpp
,neuron_layers.hpp
, orvision_layers.hpp
. Include an inline implementation of type and the Blobs() methods to specify blob number requirements. Omit the _gpu declarations if you’ll only be implementing CPU code. - Implement your layer in
layers/your_layer.cpp
. - SetUp for initialization: reading parameters, allocating buffers, etc.
Forward_cpu for the function your layer computes
Backward_cpu for its gradient
(Optional) Implement the GPU versions Forward_gpu and Backward_gpu in layers/your_layer.cu. - Add your layer to
proto/caffe.proto
, updating the next available ID. Also declare parameters, if needed, in this file. - Make your layer createable by adding it to layer_factory.cpp.
- Write tests in test/test_your_layer.cpp. Use test/test_gradient_check_util.hpp to check that your Forward and Backward implementations are in numerical agreement.
include/caffe/vision_layers.hpp
1 | #include "caffe/blob.hpp" |
2015/11/1
add new layer: crop layer
- add
Crop_layers.cpp
to source/caffe/layers - add CROP ID 40 to
caffe.proto
- add class croplayer to
visual_layer.hpp
1
2/home/xizeng/proj/caff/include/caffe/vision_layers.hpp:536:18: error: LayerParameter_LayerType▒ does not name a type
virtual inline LayerParameter_LayerType type() const {
object netParameter
- define in
caffe.proto
- arrtri:
LayerParameter
,input
,input_dim
,force_backward
,NetState
blob.hpp1
2
3
4#include "caffe/common.hpp"
#include "caffe/proto/caffe.pb.h"
#include "caffe/syncedmem.hpp"
#include "caffe/util/math_functions.hpp"
attribute:
data
diff
count
capacity
python: module, class and namespace, and library
module
A module is simply a file containing Python code. This code can be in the form of Python classes
, functions
, or just a list of names
. Each module gets it’s own global namespaces.1
2
3
4
5
6
7module1 called Integer
module2 called FloatingPoint
both have function named add().
// Once you import the module into your script,
// you can access the names by prefixing them with the module name:
FloatingPoint.add()
Integer.add().
import1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#1
import SomeModule
//call by
SomeModule.function()
#2
from SomeModule import SomeName
//no longer have to use a prefix
// in Interger.py define function add()
from Interger import add
a = add(1,2)
// but if your program has an add() function
// you’ll lose access to the Integer’s add() function.
#3
from SomeModule import *
#4
import SomePackage
import scipy
print scipy.pi + 'from the scipy package'
import math
print math.pi + 'from the math module'
namespace
- namespaces are just containers for mapping names to objects
1
2a_namespace = {'name_a':object_1, 'name_b':object_2, ...}
b_namespace = {'name_a':object_3, 'name_b':object_4, ...}
Namespaces are also searched for names inside out. This means that if there is a certain name declared in the module’s global namespace, you can reuse the name inside a function while being certain that any other function will get the global name.
classes
Classes and namespaces have special interactions. The only way for a class’ methods to access it’s own variables or functions (as names) is to use a reference to itself.
the first argument of a method must be a ‘self’ parameter, if it to access other class attributes
the module has a global namespace, the class itself does not
below is different from other object-oriented languages
can def multi class in one modules1
2
3
4
5
6
7
8
9
10// in same python/modlues file / in same namespace
global data1;
global data2;
class Fruit{
// define a function in the class and call the class object itself
def add(self,color){
....
}
}
library
a very good command for exploring library
1 | import urllib // a library |
caffe
in caffe\__init__.py
- import the function or attributes defined in other file in the same directory
log for bugs:
1 | I0706 11:00:31.481590 8842 data_transformer.cpp:22] Loading mean file from: data/ilsvrc12/imagenet_mean.binaryproto |
原因是create_cifar10的时候设置了dbtype是leveldb但是train_text_prototxt(定义net)的时候用的是lmdb所以找不到train_imdb file